#pragma once

#include <iostream>
#include <unistd.h>
#include<memory>
#include"socket.hpp"
#include "log.hpp"

using namespace logmodule;
using namespace socketmodule;
const static int size = sizeof(fd_set)*8;
const static int  defaultfd = -1;
class SelectServer
{
    
    public:
    SelectServer(int port):_listensock(std::make_unique<Tcpsocket>())
    {
        _listensock->BuildTcpsocket(port);
        for(int i= 0;i<size;i++)
        {
            fd_array[i] = defaultfd;
        }
        fd_array[0] = _listensock->Fd();
    }
    void accepter()
    {
         inetaddr client;
        int fd = _listensock->accepting(&client);
        int pos = 0;
        if(fd>=0)
        {
            //将新的fd托管到select,放入辅助数组
            for(;pos< size ;pos++)
            {
                if(fd_array[pos]==defaultfd)
                {
                    fd_array[pos] = fd;
                }
            }
            if(pos == size)
            {
                close(fd);
            }
        }
    }
    void handerevent(fd_set& rfds)
    {
        for(int i= 0;i<size;i++)
        {
            if(fd_array[i]==defaultfd)
            {
                continue;
            }
            //合法的文件描述符
            if(FD_ISSET(fd_array[i],&rfds))
            {
                //有这个文件描述符，读就绪了
                if(fd_array[i] == _listensock->Fd())
                {
                    //新连接来了
                    accepter();
                }
                else
                {
                    //其他事件就绪
                }
            }
        }
    
        // inetaddr client;
        // int fd = _listensock->accepting(&client);
        // int pos = 0;
        // if(fd>=0)
        // {
        //     //将新的fd托管到select,放入辅助数组
        //     for(;pos< size ;pos++)
        //     {
        //         if(fd_array[pos]==defaultfd)
        //         {
        //             fd_array[pos] = fd;
        //         }
        //     }
        //     if(pos == size)
        //     {
        //         close(fd);
        //     }
        // }
    }
    void Receiver(int fd,int pos)
    {
        //读东西不会阻塞
        char buffer[1024];
        ssize_t n = recv(fd,buffer,sizeof(buffer)-1,0);
        if(n>0)
        {
            buffer[n] = 0;
            std::cout<<""<<std::endl;
        }
        else if(n ==0)
        {
            //客户端退出
            //在辅助数组中去掉
            

            //关闭
            close(fd);
        }
        else
        {

        }
    }
    void start()
    {
        _isrunning = true;
        while(_isrunning)
        {
            fd_set rfds;
            FD_ZERO(&rfds);
            int maxfd = defaultfd;
           for(int i=0;i<size;i++)
           {
            if(fd_array[i]==defaultfd)
            {
                continue;
            }
             FD_SET(fd_array[i],&rfds);
             //更新最大文件描述符值
             if(maxfd<fd_array[i])
             {
                maxfd = fd_array[i];
             }

           }
            //select要借助一个辅助数组，保存历史上 关心的文件描述符
             struct timeval timeout = {2,0};
            int n = select(maxfd+1,&rfds,nullptr,nullptr,&timeout);
           
            switch(n)
            {
                case -1 :
                break;
                case 0 :
                break;
                default:
                //有事件就绪
                //要处理事件了
                handerevent(rfds);
                break;
            }
        }
        _isrunning = false;
    }
    ~SelectServer()
    {}
    private:
    std::unique_ptr<Socket> _listensock;
    bool _isrunning;
    int fd_array[size];
};
